import {PATCH_TYPE} from "./diff";
import {render, setAttr} from "./element";

let allPatches;
let index = 0; // 默认哪个需要打补丁
function patch(node, patches) {
    // 给元素打补丁
    allPatches = patches;
    walk(node)
}
// 递归树遍历
function walk(node) {
    let currentPatch = allPatches[index++];
    let childNodes = node.childNodes;
    childNodes.forEach(child => walk(child));
    // 先找后代，直到没有后代后再打补丁。补丁操作在查找后代后面。
    if (currentPatch && currentPatch.length) { // 如果补丁存在
        doPatch(node, currentPatch);
    }
}

// 打补丁
function doPatch(node, patches) {
    patches.forEach(path => {
        switch (path.type) {
            case PATCH_TYPE.ATTRS:
                for (let key in path.attrs) {
                    let value = path.attrs[key];
                    if (value) {
                        setAttr(node, key, value);
                    } else {
                        node.removeAttribute(key);
                    }
                }
                break;
            case PATCH_TYPE.TEXT:
                node.textContent = path.text;
                break;
            case  PATCH_TYPE.REPLACE:
                const newNode = path.newNode ? render(path.newNode) : document.createTextNode(path.newNode);
                node.parentNode.replaceChild(newNode, node);
                break;
            case PATCH_TYPE.REMOVE:
                node.parentNode.removeChild(node);
                break;
        }
    })
}

export default patch;